
#include "HUD.h"
#include "Input/Input.h"
#include "Graphics/GraphicsBase.h"
#include "World.h"
#include "Settings.h"
#include "GameState.h"

#include <GL/gl.h>
#include <cmath>
#include <iostream>
#include <sstream>

HUD& HUD::instance(void){
    static HUD hud;
    return hud;
}


void HUD::update(void){
    Vector2D mouse_screen_pos = Input::instance().getMousePosition();
    Vector2D screen_centre((float)GraphicsBase::getScreenWidth()/2.0f, (float)GraphicsBase::getScreenHeight()/2.0f);

    Vector2D mouse_offset = mouse_screen_pos - screen_centre;
    
    float world_xoffset = mouse_offset.x/screen_centre.x * GraphicsBase::getCameraHeight() * tan(M_PI/180.0f * 45.0/2.0f * 1024.0f/768.0f);
    float world_yoffset = mouse_offset.y/screen_centre.y * GraphicsBase::getCameraHeight() * tan(M_PI/180.0f * 45.0/2.0f);

    cursor_world_pos.x = World::instance().getCurrentFocusPoint().x + world_xoffset;
    cursor_world_pos.y = World::instance().getCurrentFocusPoint().y - world_yoffset;
}

void HUD::renderCursor(void){
    // we render the cursor in world space, not screen space
    glPushMatrix();
    glTranslatef(cursor_world_pos.x, cursor_world_pos.y, 0.0f);
    glColor3f(1.0f, 1.0f, 1.0f);

    glBegin(GL_LINE_STRIP);
      glVertex3f(-csize/2.0f, -csize/2.0f, 0.0f);
      glVertex3f(-csize/2.0f, csize/2.0f, 0.0f);
      glVertex3f(csize/2.0f, csize/2.0f, 0.0f);
      glVertex3f(csize/2.0f, -csize/2.0f, 0.0f);
      glVertex3f(-csize/2.0f, -csize/2.0f, 0.0f);
    glEnd();

    glPopMatrix();
}

void HUD::renderCursorOrtho(void){
    Vector2D mouse_screen_pos = Input::instance().getMousePosition();
    //y coord divide by the height
    //x coord divide by the width
    float x_coord = mouse_screen_pos.x /
        Settings::instance().getFloatValue("graphics","screen_width");
    float y_coord = mouse_screen_pos.y /
        Settings::instance().getFloatValue("graphics","screen_height") * 0.75f;
    float osize = csize / 10.0f;
    y_coord = 0.75f - y_coord;
    //std::cerr << "RenderCursor ( " << x_coord << " , " << y_coord << ",, " << osize << ")\n";
    glDisable(GL_TEXTURE_2D);
    glPushMatrix();
    glColor3f(1.0f, 1.0f, 1.0f);
    glTranslatef(x_coord, y_coord, 0.0f);

    glBegin(GL_LINE_STRIP);
      glVertex3f(-osize/2.0f, -osize/2.0f, 0.0f);
      glVertex3f(-osize/2.0f, osize/2.0f, 0.0f);
      glVertex3f(osize/2.0f, osize/2.0f, 0.0f);
      glVertex3f(osize/2.0f, -osize/2.0f, 0.0f);
      glVertex3f(-osize/2.0f, -osize/2.0f, 0.0f);
    glEnd();

    glPopMatrix();
}

void HUD::renderHUD(void){
    GraphicsBase::switchToOrthographic();
   
    //glDisable(GL_BLEND);
    //glDisable(GL_TEXTURE_2D); 

    minimap->render();
    renderHealthBar();
    renderEnergyBar();
    //renderScore(); 
    //console.render();
    

    /*
    glPushMatrix();
    glTranslatef(0.1f, 0.1f, 0.0f);
    glColor4f(1.0, 1.0, 1.0f, 1.0f);
    hud_font.renderString("hello world");
    glPopMatrix();
*/
    GraphicsBase::switchFromOrthographic();
}

Vector2D HUD::getCursorWorldPosition(void){
    return cursor_world_pos;
}


void HUD::renderScore(void){
    std::stringstream tmp_stream;
    tmp_stream << "Red:  " << GameState::instance().getTeamScore(0);

    glPushMatrix();
    glColor3f(1.0f, 0.0f, 0.0f);
    glTranslatef(0.03f, 0.1f, 0.0f);
    hud_font.renderString(tmp_stream.str());
    glPopMatrix();

    tmp_stream.flush();
    tmp_stream.seekp(0);
    tmp_stream << "Blue: " << GameState::instance().getTeamScore(1);

    glPushMatrix();
    glColor3f(0.0f, 0.0f, 1.0f);
    glTranslatef(0.03f, 0.05f, 0.0f);
    hud_font.renderString(tmp_stream.str());
    glPopMatrix();
}


void HUD::renderHealthBar(void){
    Ship *pship = World::instance().getControlPlayer()->getShip();
    float health = 0.0f; 

    if(pship != NULL){ health = pship->getHealth(); }

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDepthMask(GL_FALSE);

    glBegin(GL_QUADS);

    glColor4f(0.0f, 1.0f, 0.0f, 0.2f);
    glVertex3f(0.7f, 0.1f, 0.0f);
    glVertex3f(0.7f, 0.08f, 0.0f);

    float alpha = std::max<float>(0.2f, health/100.0f);
    glColor4f(0.0f, 1.0f, 0.0f, alpha);
    glVertex3f(0.7f + 0.25f*health/100.0f, 0.08f, 0.0f);
    glVertex3f(0.7f + 0.25f*health/100.0f, 0.1f, 0.0f);

    glEnd();

    glDepthMask(GL_TRUE);
    glDisable(GL_BLEND);
}


void HUD::renderEnergyBar(void){
    Ship *pship = World::instance().getControlPlayer()->getShip();
    float energy = 0.0f; 

    if(pship != NULL){ energy = pship->getEnergy(); }

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDepthMask(GL_FALSE);

    glBegin(GL_QUADS);

    glColor4f(0.0f, 0.0f, 1.0f, 0.2f);
    glVertex3f(0.7f, 0.07f, 0.0f);
    glVertex3f(0.7f, 0.05f, 0.0f);

    float alpha = std::max<float>(0.2f, energy/100.0f);
    glColor4f(0.0f, 0.0f, 1.0f, alpha);
    glVertex3f(0.7f + 0.25f*energy/100.0f, 0.05f, 0.0f);
    glVertex3f(0.7f + 0.25f*energy/100.0f, 0.07f, 0.0f);

    glEnd();

    glDepthMask(GL_TRUE);
    glDisable(GL_BLEND);
}


HUD::HUD() : cursor_world_pos(0.0f, 0.0f), 
             csize(Settings::instance().getFloatValue("hud", "cursor_size")), 
             hud_font(Settings::instance().getStringValue("hud", "font_file"), 0.02f, 0.015f), // TODO: font size/spacing read from settings
             console(Vector2D(0.2f, 0.02f), Vector2D(0.8f, 0.15f)) { // TODO read from settings

    Vector2D minimap_pos(Settings::instance().getFloatValue("hud", "minimap_pos_x"), 
                         Settings::instance().getFloatValue("hud", "minimap_pos_y"));

    minimap = new Minimap(minimap_pos, Settings::instance().getFloatValue("hud", "minimap_size"));
    console.addEntry("hello world");
    console.addEntry("anal bum fuck");
    console.addEntry("I think youre Gay!!");
    console.addEntry("I am a big fat and AWESOME");
}

  
HUD::~HUD(){
    delete minimap;
}

